package com.supreme.cacheserver.controller;

import com.supreme.commonboot.utils.AjaxResp;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@RestController
@RequestMapping(value = "redis-lua")
public class RedisLuaController {

    @Resource
    private RedisTemplate<String, Serializable> redisTemplate;

    @GetMapping(value = "getValue/shell/{key}")
    public AjaxResp getValueByShell(@PathVariable(value = "key") String key) {
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>("return redis.call('GET', KEYS[1])", String.class);
        RedisSerializer<String> argsSerializer = redisTemplate.getStringSerializer();
        RedisSerializer<String> resultSerializer = redisTemplate.getStringSerializer();
        String result = redisTemplate.execute(redisScript, argsSerializer, resultSerializer, Collections.singletonList(key));
        return AjaxResp.instance(result);
    }

    @GetMapping(value = "getValue/{key}")
    public AjaxResp getValue(@PathVariable(value = "key") String key) {
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
        ClassPathResource classPathResource = new ClassPathResource("lua/getValue.lua");
        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(classPathResource);
        redisScript.setScriptSource(resourceScriptSource);
        redisScript.setResultType(String.class);
        String result = redisTemplate.execute(redisScript, Collections.singletonList(key));
        return AjaxResp.instance(result);
    }

    @GetMapping(value = "setValue/{key}/{value}")
    public AjaxResp setValue(@PathVariable(value = "key") String key, @PathVariable(value = "value") String value) {
        DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
//        ClassPathResource classPathResource = new ClassPathResource("lua/setValue.lua");
//        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(classPathResource);
//        redisScript.setScriptSource(resourceScriptSource);
        redisScript.setScriptText("redis.call('SET', KEYS[1], ARGV[1])");
        redisScript.setResultType(String.class);
        redisTemplate.execute(redisScript, Collections.singletonList(key), value);
        return AjaxResp.instance();
    }

    @GetMapping(value = "bfReserve/{key}/{errorRate}/{initSize}")
    public AjaxResp bfReserve(@PathVariable(value = "key") String key,
                              @PathVariable(value = "errorRate") String errorRate,
                              @PathVariable(value = "initSize") String initSize) {
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
        ClassPathResource classPathResource = new ClassPathResource("lua/bloomFilterReserve.lua");
        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(classPathResource);
        redisScript.setScriptSource(resourceScriptSource);
        redisScript.setResultType(Boolean.class);
        Boolean execute = redisTemplate.execute(redisScript, Arrays.asList(key, errorRate, initSize));
        return AjaxResp.instance(execute);
    }

    @GetMapping(value = "bfAdd/{key}/{value}")
    public AjaxResp bfAdd(@PathVariable(value = "key") String key, @PathVariable(value = "value") String value) {
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
        ClassPathResource classPathResource = new ClassPathResource("lua/bloomFilterAdd.lua");
        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(classPathResource);
        redisScript.setScriptSource(resourceScriptSource);
        redisScript.setResultType(Boolean.class);
        Boolean execute = redisTemplate.execute(redisScript, Arrays.asList(key, value));
        return AjaxResp.instance(execute);
    }

    @GetMapping(value = "bfMultiAdd/{key}/{value}")
    public AjaxResp bfMultiAdd(@PathVariable(value = "key") String key, @PathVariable(value = "value") String... value) {
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
        ClassPathResource classPathResource = new ClassPathResource("lua/bloomFilterMultiAdd.lua");
        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(classPathResource);
        redisScript.setScriptSource(resourceScriptSource);
        redisScript.setResultType(Boolean.class);
        Boolean execute = redisTemplate.execute(redisScript, Collections.singletonList(key), value);
        return AjaxResp.instance(execute);
    }

    @GetMapping(value = "bfExist/{key}/{value}")
    public AjaxResp bfExist(@PathVariable(value = "key") String key, @PathVariable(value = "value") String value) {
        DefaultRedisScript<Boolean> redisScript = new DefaultRedisScript<>();
        ClassPathResource classPathResource = new ClassPathResource("lua/bloomFilterExists.lua");
        ResourceScriptSource resourceScriptSource = new ResourceScriptSource(classPathResource);
        redisScript.setScriptSource(resourceScriptSource);
        redisScript.setResultType(Boolean.class);
        Boolean execute = redisTemplate.execute(redisScript, Arrays.asList(key, value));
        return AjaxResp.instance(execute);
    }
}
